#include "meshTypes.hpp"
#include "meshFunctions.hpp"
#include "vtkMeshExport.hpp"
#include "vtkFunctions_export.hpp"

#include "testFunctions.hpp"
#include "mesh_testFunctions.hpp"

#include <catch2/catch_test_macros.hpp>
#include <sstream>

using namespace hms;

TEST_CASE( "Creating VTK XML from mesh", "[pureOutput]" ){
	using namespace hms;
	using namespace hms::vtk;
	MeshVariant meshVar;
	/* these "tests" are kept for convenience, but they don't test anything and
	 * all output is suppressed with the next line */
	suppressOutput();
	SECTION( "UniMesh" ){
		meshVar.emplace<UniMesh>(
			4, 5, 0.1, 0.2, Vector2s{3.0, -0.2}
		);
		// resetOutput();
		std::cout << "UniMesh:\n";
		auto meshDoc { meshToVtk(meshVar) };
		toStream( meshDoc.get(), std::cout );
		std::cout << "\n";
	}
	SECTION( "RectMesh" ){
		VectorXs xCoords (5);
		VectorXs yCoords (7);
		xCoords << -0.1, 1.5, 3.0, 4.4, 5.7;
		yCoords <<  0.3, 0.5, 0.9, 1.5, 2.3, 3.3, 4.5;
		meshVar.emplace<RectMesh>(
			std::move(xCoords),
			std::move(yCoords)
		);
		std::cout << "RectMesh:\n";
		auto meshDoc { meshToVtk(meshVar) };
		toStream( meshDoc.get(), std::cout );
		std::cout << "\n";
	}
	SECTION( "StructMesh" ){
		Matrix2Xs vertices (2,12);
		vertices <<
			0, 1, 3, 0, 1, 3, 0, 1, 3, 0, 1, 3,
			1, 1, 1, 3, 3, 3, 4, 4, 4, 8, 8, 8;
		/* distort the grid by translating every other vertex a bit */
		vertices(hms::all, Eigen::seqN(1,6,2)).colwise() += Vector2s{0.2,-0.3};
		meshVar.emplace<StructMesh>( std::move(vertices), 2, 3 );
		
		std::cout << "StructMesh:\n";
		auto meshDoc { meshToVtk(meshVar) };
		toStream( meshDoc.get(), std::cout );
		std::cout << "\n";
	}
	SECTION( "Mesh" ){
		meshVar.emplace<Mesh>( testMeshTriangles(true) );
		std::cout << "Mesh:\n";
		auto meshDoc { meshToVtk(meshVar) };
		toStream( meshDoc.get(), std::cout );
		std::cout << "\n";
	}
	SECTION( "Mesh with boundary patches" ){
		// resetOutput();
		meshVar.emplace<Mesh>( createRectangularMesh(2,3,1.1,1.4) );
		// resetOutput();
		std::cout << "Mesh with boundary patches:\n";
		auto meshDoc { meshToVtk(meshVar) };
		auto boundaryDoc { boundaryToXML(meshVar) };
		toStream( meshDoc.get(), std::cout );
		toStream( boundaryDoc.get(), std::cout );
		std::cout << "\n";
	}
	
	resetOutput();
}